package com.jeasonzhao.commons.parser.lex;

public class LexToken implements java.io.Serializable
{
    private static final long serialVersionUID = 1L;
    private int position = -1; //Start position
    private int beginRowIndex = 0;
    private int beginColumn = 0;

    private String token = "";
    private String prefix = null,suffix = null;
    private LexTokenTypes type = LexTokenTypes.NULL;
    private int endRowIndex = 0;

    private LexToken m_prevBlanks = null;
    private LexToken()
    {
        type = LexTokenTypes.NULL;
    }

    public static LexToken create(String str)
    {
        if(null == str)
        {
            return null;
        }
        LexToken token = new LexToken();
        token.type = LexTokenTypes.STRING_QUOTED;
        token.token = str;
        return token;
    }

    public int hashCode()
    {
        return null == token ? -1 : token.hashCode();
    }

    public static LexToken create(int nPosition,int nBeginRowIndex,int nBeingColumn)
    {
        LexToken token = new LexToken();
        token.position = nPosition;
        token.beginRowIndex = nBeginRowIndex;
        token.beginColumn = nBeingColumn;
        return token;
    }

    public void clear()
    {
        this.position = -1;
        this.token = "";
        this.type = LexTokenTypes.NULL;
        beginColumn = 0;
        beginRowIndex = 0;
        endRowIndex = 0;
    }

    public boolean isStartWithSpecial()
    {
        if(null == token || token.length() < 1)
        {
            return false;
        }
        else
        {
            char c = token.charAt(0);
            return Character.isDigit(c) == false &&
                Character.isSpaceChar(c) == false &&
                Character.isLetter(c) == false;
        }
    }

    public boolean isSpecial()
    {
        return type == LexTokenTypes.SPECIAL;
    }

    public boolean isComment()
    {
        return type == LexTokenTypes.COMMENT_BLOCK || type == LexTokenTypes.COMMENT_LINE;
    }

    public boolean isName()
    {
        return type == LexTokenTypes.NAME || type == LexTokenTypes.LONG_NAME;
    }

    public boolean isNumeric()
    {
        return type == LexTokenTypes.NUMBER || type == LexTokenTypes.DOUBLE;
    }

    public boolean isString()
    {
        return type == LexTokenTypes.STRING || type == LexTokenTypes.STRING_QUOTED;
    }

    public int getBeginColumn()
    {
        return beginColumn;
    }

    public int getBeginRowIndex()
    {
        return beginRowIndex;
    }

    public int getEndRowIndex()
    {
        return endRowIndex;
    }

    public LexToken getPrevBlanks()
    {
        return m_prevBlanks;
    }

    public int getPosition()
    {
        return position;
    }

    public String getToken()
    {
        return token;
    }

    public LexTokenTypes getType()
    {
        return type;
    }

    public String getSuffix()
    {
        return suffix;
    }

    public String getPrefix()
    {
        return prefix;
    }

    public void setType(LexTokenTypes type)
    {
        this.type = type;
    }

    public void setToken(String token)
    {
        this.token = token;
    }

    public void setPosition(int position)
    {
        this.position = position;
    }

    public void setPrevBlanks(LexToken m_prevBlanks)
    {
        this.m_prevBlanks = m_prevBlanks;
    }

    public void setEndRowIndex(int endRowIndex)
    {
        this.endRowIndex = endRowIndex;
    }

    public void setBeginRowIndex(int beginRowIndex)
    {
        this.beginRowIndex = beginRowIndex;
    }

    public void setBeginColumn(int beginColumn)
    {
        this.beginColumn = beginColumn;
    }

    public void setSuffix(String suffix)
    {
        this.suffix = suffix;
    }

    public void setPrefix(String prefix)
    {
        this.prefix = prefix;
    }

    public String toString()
    {
        return
            (this.prefix == null ? "" : this.prefix) +
            this.getToken() +
            (this.suffix == null ? "" : this.suffix);
    }

    public boolean equals(String str)
    {
        return null == this.getToken() ? str == null : this.getToken().equals(str);
    }

    public boolean equals(Object obj)
    {
        if(null == obj)
        {
            return false;
        }
        if(obj instanceof LexToken)
        {
            LexToken x = (LexToken) obj;
            return x.getToken().equals(this.getToken()) &&
                x.getType() == this.getType();
        }
        else
        {
            String str = obj.toString();
            return this.getToken().equals(str);
        }
    }

    public String getInitString()
    {
        return replaceToken(null);
    }

    public String replaceToken(String strReplace)
    {
        String str = strReplace == null ? this.getToken() : strReplace;
        return(null == this.getPrevBlanks() ? "" : this.getPrevBlanks().getToken()) +
            (null == this.getPrefix() ? "" : this.getPrefix()) + str +
            (null == this.getSuffix() ? "" : this.getSuffix());
    }

    public void moveToPrevToken(LexToken t)
    {
        if(null == t)
        {
            return;
        }
        this.token = t.getToken() +
            (null == this.getSuffix() ? "" : this.getSuffix()) +
            (null == this.getPrevBlanks() ? "" : this.getPrevBlanks().getToken()) +
            (null == this.getPrefix() ? "" : this.getPrefix()) + this.getToken();
        this.prefix = t.prefix;
        this.m_prevBlanks = t.m_prevBlanks;
        this.beginColumn = t.beginColumn;
        this.beginRowIndex = t.beginRowIndex;
    }
}
